package basicobject

import (
	"github.com/pkg/errors"
	"yizhuoyan/go-study/pdfgo/handyio"
)

var startDictionaryKeywordBytes = []byte("<<")
var endDictionaryKeywordBytes = []byte(">>")

type Dictionary struct {
	value map[string]BasicObject
}

func NewDictionary() *Dictionary {
	return &Dictionary{
		value: make(map[string]BasicObject, 4),
	}
}

func (this *Dictionary) Put(key string, value BasicObject) BasicObject {
	if old, has := this.value[key]; has {
		this.value[key] = value
		return old
	}
	this.value[key] = value
	return nil
}
func (this *Dictionary) Get(key string) BasicObject {
	return this.value[key]
}
func (this *Dictionary) MustGetArray(key string) *Array {
	if v, has := this.value[key]; has {
		return v.(*Array)
	}
	return nil
}
func (this *Dictionary) MustGetDictionary(key string) *Dictionary {
	if v, has := this.value[key]; has {
		return v.(*Dictionary)
	}
	return nil
}
func (this *Dictionary) MustGetInteger(key string) *Integer {
	if v, has := this.value[key]; has {
		return v.(*Integer)
	}
	return nil
}
func (this *Dictionary) MustGetName(key string) *Name {
	if v, has := this.value[key]; has {
		return v.(*Name)
	}
	return nil
}
func (this *Dictionary) HasKey(key string) bool {
	if _, has := this.value[key]; has {
		return true
	}
	return false
}
func (this *Dictionary) HasKeyAndNameValue(key, value string) bool {
	if v, has := this.value[key]; has {
		if nameV, is := v.(*Name); is {
			if value == nameV.GetNameValue() {
				return true
			}
		}
		return false
	}
	return false
}

func (this *Dictionary) MustGetIndirectObjectReference(key string) *IndirectObjectReference {
	if v, has := this.value[key]; has {
		return v.(*IndirectObjectReference)
	}
	panic(errors.Errorf("dictionary无key:%s", key))
}
func (this *Dictionary) Serialize(w handyio.PdfRawWriter) error {
	w.WriteBytes(startDictionaryKeywordBytes)
	for k, v := range this.value {
		w.WriteBytes([]byte(k))
		w.WriteByte(' ')
		if err := v.Serialize(w); err != nil {
			return err
		}
	}
	w.WriteBytes(endDictionaryKeywordBytes)
	return nil
}

func (this *Dictionary) UnSerialize(r handyio.PdfRawReader) error {
	startAt := r.IndexCurrent()
	if !r.NextBytesEquals(startDictionaryKeywordBytes) {
		return r.NotSupport("无开始标记<<")
	}
	r.SkipNextWhiteSpaces()
	var rst = make(map[string]BasicObject, 10)
	for !r.NextBytesEquals(endDictionaryKeywordBytes) {
		var nameKey = new(Name)
		if err := nameKey.UnSerialize(r); err != nil {
			_ = r.IndexMoveTo(startAt)
			return errors.Wrapf(err, "UnSerialize Dictionary key")
		}
		r.SkipNextWhiteSpaces()
		if obj, err := ReadrBasicObject(r); err != nil {
			_ = r.IndexMoveTo(startAt)
			return errors.Wrapf(err, "UnSerialize Dictionary %s value", nameKey.GetNameValue())
		} else {
			rst[nameKey.GetNameValue()] = obj
		}
		r.SkipNextWhiteSpaces()
	}
	this.value = rst
	return nil

}
